﻿using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;

namespace UDITest
{
    public class SerialTool
    {
        Dictionary<string, SerialPort> AllSerial { get; set; } = new Dictionary<string, SerialPort>();

        Action<string> _dataAction;

        private int StringToHex(string str)
        {
            //str = str.Replace("0x", "").Replace("0X", "");
            return Convert.ToInt32(str, 16);
        }

        /// <summary>
        /// 打开设备
        /// </summary>
        /// <param name="vid"></param>
        /// <param name="pid"></param>
        /// <param name="dataAction"></param>
        public bool Open(string vid, string pid, Action<string> dataAction)
        {
            var coms = DeviceHelper.GetCOMFromVIDPID(StringToHex(vid), StringToHex(pid));

            if (coms.Length == 0) throw new Exception("未找到串口设备");

            foreach (var item in coms)
            {
                if (!AllSerial.Keys.Contains(item))
                {
                    Conn(item, dataAction);
                }
            }
            return AllSerial.Count > 0;
        }

        public bool CheckConn()
        {
            List<string> needRemove = new List<string>();
            foreach (var item in AllSerial)
            {
                if (!item.Value.IsOpen)
                {
                    needRemove.Add(item.Key);
                }
            }
            needRemove.ForEach(t => AllSerial.Remove(t));
            return AllSerial.Count > 0;
        }



        private void Conn(string com, Action<string> dataAction)
        {
            SerialPort serialPort = new SerialPort(com, 9600); // 创建串口实例

            serialPort.Open(); // 打开串口
            _dataAction = dataAction;
            serialPort.DataReceived += SerialPort_DataReceived;
            AllSerial.Add(com, serialPort);
        }

        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            var sp = (SerialPort)sender;
            _dataAction?.Invoke(sp.ReadExisting());
        }

        public void Close()
        {
            foreach (var item in AllSerial)
            {
                try
                {
                    if (item.Value != null)
                    {
                        item.Value.DataReceived -= SerialPort_DataReceived;
                        item.Value.Close();
                        item.Value.Dispose();
                    }
                }
                catch (Exception)
                {

                }
            }
            AllSerial.Clear();
        }
    }
}
